/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author antonio
 */
import java.util.Random;
import vmm.algs.PPMCPredictor;

public class Node {
	int wiring_credits; 
	PPMCPredictor ppm; /* Markov model estimation algorithm */
	int order; /* Markov order. Matches the number of major dendritic brances */
	int id; 
	int layer; 
	CharSequence in; /* node actual input */
	double epsilon;
	Random rand;
	int coordinate; /* 1-D coordinate */

	public Node(int order, int x)
	{
		this.ppm = new PPMCPredictor();
		this.order = order;
		this.epsilon = 1.0;
		this.rand = new Random();
		this.wiring_credits = 100;
		this.coordinate = x;
	}
	
	public static boolean containsInformation(CharSequence cs)
	{
		String b = (String) cs;
		b = b.replaceAll("0", "");
		String empty = "";
		if(b.contentEquals(empty))
		{
			//System.out.println("Happens!");
			return false;
		}
		else
			return true;
	}
	
	public void input(CharSequence buffer) throws Exception
	{
		this.in = buffer;
		double pseudoRand = this.rand.nextDouble(); 
		if(pseudoRand <= this.epsilon && containsInformation(buffer))
		{
			this.ppm.learn(buffer);
			if(this.epsilon > 0.05)
			{
				this.epsilon -= 0.00005;
			}
			//System.out.println(pseudoRand + " Open! " + this.epsilon);
		}
	}
	
	public void setId(int l,int la)
	{
		this.id = l;
		this.layer = la;
		this.ppm.init(127, this.order-la);
	}
	
	public CharSequence output()
	{
		String out = "";
		int len = in.length()/this.order;
		double losses[] = new double[len];
		int k = 0;
		double best = +2147483648.0;
		CharSequence pattern = "";
		for(int i = 0; i < in.length()-this.order-1; i+= this.order)
		{
			//System.out.println(in.length() + "," +i + "," + order);
			CharSequence context = this.in.subSequence(i, i+this.order-1);
			losses[k] = this.ppm.logEval(context);
			if(losses[k] < best && containsInformation(context))
			{
				best = losses[k++];
				pattern = context;
				//this.ppm.predict(Character.getNumericValue(this.in.charAt(i+this.order)), context);
			}
		}
		for(int i = 0; i < in.length()-this.order-1; i+= this.order)
		{
			CharSequence context = this.in.subSequence(i, i+this.order-1);
			//double loss = this.ppm.logEval(context);
			//if(loss == best)
			//if(pattern.equals(context))
			int allowed = (int) (1 + pattern.length()*0.4);
			//if(LevenshteinDistance.computeLevenshteinDistance(pattern,context) < allowed)
			if(LevenshteinDistance.computeLevenshteinDistance(pattern,context) < allowed && containsInformation(context))
				out += "1";
			else
				out += "0";
		}
		//System.out.println("{" + this.in + "}:" + this.id + "[" + this.layer + "]:" + out);
		//System.out.println(this.id + "," + this.layer + "," + this.in);
		return out;
	}
}
